package com.example.his.api.common;


import cn.hutool.core.codec.Base64;
import com.example.his.api.exception.HisException;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@Component
@Slf4j
public class MinioUtil {
  
  @Value("${minio.endpoint}")
  private String endpoint;
  
  @Value("${minio.access-key}")
  private String accessKey;
  
  @Value("${minio.secret-key}")
  private String secretKey;
  
  @Value("${minio.bucket}")
  private String bucket;
  
  private MinioClient client;
  
  @PostConstruct
  public void init() {
    this.client = new MinioClient.Builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
  }
  
  //  上传图片
  public void uploadImage(String path, MultipartFile file) {
    try {
      //      向minio中保存图片，文件大小不能超过5M
      this.client.putObject(new PutObjectArgs.Builder().bucket(bucket).object(path).stream(file.getInputStream(), - 1, 5 * 1024 * 1024).contentType("image/jpeg").build());
      log.debug("向" + path + "保存了文件");
    } catch(Exception e) {
      log.error("保存文件失败", e);
      throw new HisException("保存文件失败");
    }
  }
  
  //  上传excel表格
  public void uploadExcel(String path, MultipartFile file) {
    try {
      //      Excel 文件的MIME类型
      String mime = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
      //      Excel文件不能超过20M
      this.client.putObject(PutObjectArgs.builder().bucket(bucket).object(path).stream(file.getInputStream(), - 1, 20 * 1024 * 1024).contentType(mime).build());
      log.debug("向" + path + "保存了文件");
      
    } catch(Exception e) {
      log.error("Excel文件保存失败", e);
      throw new HisException("保存文件失败");
    }
  }
  
  //  下载文件
  public InputStream downloadFile(String path) {
    try {
      GetObjectArgs args = GetObjectArgs.builder().bucket(bucket).object(path).build();
      return client.getObject(args);
    } catch(Exception e) {
      log.error("下载文件失败", e);
      throw new HisException("下载文件失败");
    }
  }
  
  //   删除保存在minio中的文件
  public void deleteFile(String path) {
    try {
      this.client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(path).build());
      log.debug("删除了" + path + "路径下的文件");
    } catch(Exception e) {
      log.error("删除文件失败", e);
      throw new HisException("文件删除失败");
    }
  }
  
  
  //  接收base64图片字符串，还原图片保存到mino服务器
  public void uploadImage(String path, String base64Image) {
    try {
      //      去掉前缀
      base64Image = base64Image.replace("data:image/jpeg;base64,", "");
      base64Image = base64Image.replace("data:image/png;base64,", "");
      byte[] decode = Base64.decode(base64Image);
      ByteArrayInputStream in = new ByteArrayInputStream(decode);
      //      保存到 minio中（文件不能超过5m）
      this.client.putObject(PutObjectArgs.builder().bucket(bucket).object(path).stream(in, - 1, 5 * 1024 * 1024).contentType("image/jpeg").build());
      log.debug("向" + path + "保存了文件");
    } catch(Exception e) {
      log.error("保存文件失败", e);
      throw new HisException("保存文件失败");
    }
  }
  
  //  将体检结果保存到minio服务器
  public void uploadWord(String path, InputStream in) {
    try {
      String mime = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
      //  向minio中保存word文档（文件不能超过50m）
      this.client.putObject(PutObjectArgs.builder().bucket(bucket).object(path).stream(in, - 1, 50 * 1024 * 1024).contentType(mime).build());
      log.debug("向" + path + "保存了文件");
      in.close();
    } catch(Exception e) {
      log.error("保存文件失败", e);
      throw new HisException("保存文件失败");
    }
    
    
  }
  
}
